﻿using System;
using System.Collections.Generic;
using CookComputing.XmlRpc;
//
using PerceptiveMCAPI.Types;
using PerceptiveMCAPI.Types.Internal;
//
namespace PerceptiveMCAPI.Methods
{
	public class campaigns : Api_BaseExecute
	{
		private new campaignsInput Input { get; set; }
		private campaignsOutput Output { get; set; }
		// =============================================== constructors
		public campaigns() { }
		// ---------
		public campaigns( campaignsInput input ) { Input = input; }
		// =============================================== Execute
		public campaignsOutput Execute()
		{
			// empty constructor & Execute() is bad
			if ( Input == null )
				throw new ArgumentException( "Input class not provided" );
			// do the deed
			Output = Execute( Input );
			return Output;
		}
		// ---------------------------------------------
		public campaignsOutput Execute( campaignsInput input )
		{
			Input = input;
			Output = new campaignsOutput( Input );
			ValidationIsOK = true;
			//-------------------------
			if ( Input.api_Validate )
			{
				Output.api_ValidatorMessages = ValidateInput.Validate( Input );
				ValidationIsOK = ValidateInput.IsOK( Output.api_ValidatorMessages );
			}
			//------------------------- do it
			if ( ValidationIsOK )
			{
				ApiRun( Input, input.parms.apikey );  // execute API & format output
			}
			// ---
			return Output;
		}

		#region ================================================================= API Calls

		// ---------------------------------------------------------- XmlRpc
		protected override void ExecuteXmlRpc()
		{
			try
			{
				var filters = FormatCampaignFilters( Input.parms.filters );
				// ---------------------------------- rpc call -------------------------------------------
				x_campaigns rpcResult = apiXmlRpc.api.campaigns( Input.parms.apikey, filters, Input.parms.start, Input.parms.limit );
				Output.Format( rpcResult );
			}
			catch ( XmlRpcFaultException fex )
			{
				Output.api_ErrorMessages.Add( apiException.FormatError( fex ) );
			}
			catch ( Exception ex )
			{
				Output.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}

		// -----------------------
		private XmlRpcStruct FormatCampaignFilters( Dictionary<string, object> filters )
		{
			XmlRpcStruct rpc = new XmlRpcStruct();
			if ( filters.Count > 0 )
			{
				string sValue = "";
				foreach ( KeyValuePair<string, object> kv in filters )
				{
					string kvtype = kv.Value.GetType().Name.ToLower();
					//
					if ( kvtype == "datetime" )
					{
						sValue = apiHelper.FormatApiDateParm( (DateTime)kv.Value );
						rpc.Add( kv.Key, sValue );
					}
					else if ( kvtype.Contains( "list`1" ) )
					{
						sValue = apiHelper.MakeStringFromObjectList( kv.Value );
						rpc.Add( kv.Key, sValue );
					}
					else
					{
						rpc.Add( kv.Key, kv.Value.ToString() ?? "" );
					}
				}
			}
			return rpc;
		}

		// ---------------------------------------------------------- SerialPost
		protected override void ExecuteSerialPost()
		{
			try
			{
				string sValue = "";
				Dictionary<string, string> dict = new Dictionary<string, string>();
				dict.Add( "apikey", Input.parms.apikey );

				foreach ( KeyValuePair<string, object> kv in Input.parms.filters )
				{
					string valuetype = kv.Value.GetType().Name.ToLower();
					//
					if ( valuetype == "datetime" )
						sValue = apiHelper.FormatApiDateParm( (DateTime)kv.Value );
					else if ( valuetype.Contains( "list`1" ) )
						sValue = apiHelper.MakeStringFromObjectList( kv.Value );
					else
						sValue = kv.Value.ToString() ?? "";
					//
					dict.Add( string.Format( "filters[{0}]", kv.Key ), sValue );
				}
				// -----------------
				if ( Input.parms.limit > 0 )
				{
					dict.Add( "start", Input.parms.start.ToString() );
					dict.Add( "limit", Input.parms.limit.ToString() );
				}
				// -- do it
				string api_Request = "";
				string api_Response = apiSerial.ProcessRequest( Input, dict, out api_Request );
				Output.Format( api_Request, api_Response );
			}
			catch ( Exception ex )
			{
				Output.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}

		#endregion
	}
}
